package com.fsh.lingsp.common.common.intercepter;

import com.fsh.lingsp.common.common.exception.HttpErrorEnum;
import com.fsh.lingsp.common.user.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
import java.util.Optional;

/**
 * 作者：fsh
 * 日期：2024/03/01
 * <p>
 * 描述：令牌拦截器
 *      从请求头中获取 token ，解析uid
 */
@Component
public class TokenIntercepter implements HandlerInterceptor {

    @Autowired
    private LoginService loginService;

    //常量  Authorization
    public static final String HEADER_AUTHORIZATION = "Authorization";
    //常量 token前缀
    public static final String BEARER_PRE_TOKEN = "Bearer ";

    /**
     * @param request  请求
     * @param response 响应
     * @param handler  处理器
     * @return boolean
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 去除前缀，拿到真正的token
        String token = getToken(request);
        // 从token中取出uid
        Long validUid = loginService.getValidUid(token);
        if (Objects.nonNull(validUid)){
            //token未过期，有uid。 存起来 todo ThreadLocal
            request.setAttribute("uid",validUid);
        }else{
            //token过期，无uid。登录失效--->未登录
            //先判断是不是 public 公共接口，是的话不用登录就可以放行
            if (!isPublicURL(request)){
                HttpErrorEnum.ACCESS_DENIED.sendHttpError(response);
                return false;
            }
        }
        return true;
    }

    //先判断是不是 public 公共接口
    private boolean isPublicURL(HttpServletRequest request) {
        // 路径格式"/capi/user/public" ， ”/“分割，”public“是[3]
        String requestURI = request.getRequestURI();
        String[] split = requestURI.split("/");
        return split.length>2 && "public".equals(split[3]);
    }


    //从请求头中截取 token ，去除前缀
    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(HEADER_AUTHORIZATION);
        //token的格式 ：Bearer jsdhajdjksadhjkashdasdkl......
        return Optional.ofNullable(token)
                .filter(s->s.startsWith(BEARER_PRE_TOKEN))
                .map(s->s.replaceFirst(BEARER_PRE_TOKEN,""))
                .orElse(null);
    }
}
